﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using AjaxControlToolkit;
using System.Net;
using System.IO;
using System.Text;

namespace HTTPDebuggerTools.com
{
    public partial class ViewHttpHeaders : System.Web.UI.Page
    {
        bool isCustomAgent = true;

        protected void Page_Load(object sender, EventArgs e)
        {
            NoBotState state;
            if (!NoBot1.IsValid(out state))
                Response.Redirect("http://www.httpdebugger.com/");


            isCustomAgent = (AgentList.SelectedValue == "Custom");

            AgentBox.CssClass = isCustomAgent ? "show" : "hide";
        }

        protected void SubmitBtn_Click(object sender, EventArgs e)
        {
            RequestHeaders.Visible = false;
            ResponseHeaders.Visible = false;

            string url = UrlBox.Text.Trim();
            if (url.Length != 0)
            {
                //if URL does not contain http(s) then add it
                if (url.IndexOf("http://") == -1 && url.IndexOf("https://") == -1)
                    url = "http://" + url;

                SendRequest(url);
            }
        }

        void SendRequest(string url)
        {
            try
            {
                // Create a request for the URL. 		
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

                SetRequestParams(ref request);

                // Get the response.
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                // Get the stream containing content returned by the server.
                Stream dataStream = response.GetResponseStream();
                // Open the stream using a StreamReader for easy access.
                StreamReader reader = new StreamReader(dataStream);

                // Read the content.
                string result = reader.ReadToEnd();

                //obtain headers before closing connection
                ShowHeaders(request, response);

                // Cleanup the streams and the response.
                reader.Close();
                dataStream.Close();
                response.Close();

                //now we can process response
                ProcessResponse(result);
            }
            catch (WebException wxp)
            {
                ResultLiteral.Text = "<span class='statuserr'>" + wxp.Message + "</span>";
            }
            catch (Exception exp)
            {
                ResultLiteral.Text = "<span class='statuserr'>" + exp.Message + "</span>";
            }
            //catch
            //{
            //    ResultLiteral.Text = "<span class='statuserr'>Error Opening URL</span>";
            //}
        }

        void SetRequestParams(ref HttpWebRequest request)
        {
            string customHeaders = HeadersBox.Text.Trim();
            string contentType = ContentTypeBox.Text.Trim();
            string contentData = ContentDataBox.Text.Trim();
            string customReferer = RefererBox.Text.Trim();

            // If required by the server, set the credentials.
            request.Credentials = CredentialCache.DefaultCredentials;

            //HTTP VERSION
            request.ProtocolVersion = (VersionsList.SelectedValue == "HTTP/1.1") ? HttpVersion.Version11 : HttpVersion.Version10;
            
            //HTTP METHOD
            request.Method = MethodList.SelectedValue;

            //CUSTOM HEADERS
            if (customHeaders.Length != 0)
            {
                customHeaders = customHeaders.Replace("\r\n", "\n");
                string[] headers = customHeaders.Split('\n');

                foreach (string header in headers)
                {                    
                    string[] vals = header.Split(':');
                    if (vals.Length == 2)
                    {
                        string name = vals[0].Trim();
                        string val = vals[1].Trim();

                        if (!WebHeaderCollection.IsRestricted(name))
                            request.Headers.Add(name, val);
                        else
                            throw new Exception("Unable to set the '" +  name + "' for the custom headers.");
                    }                
                }                    
            }

            //CONTENT TYPE AND DATA (if any)
            if (contentType.Length != 0 && contentData.Length != 0)
            {
                request.ContentType = contentType;
                request.ContentLength = contentData.Length;

                Stream newStream = request.GetRequestStream();

                //convert string to byte array and write to stream
                byte[] byteArray = Encoding.ASCII.GetBytes(contentData);
                newStream.Write(byteArray, 0, byteArray.Length);

                // Close the Stream object.
                newStream.Close();
            }

            //HTTP REFERER
            if (customReferer.Length != 0)
                request.Referer = customReferer;

            //USER AGENT
            request.UserAgent = GetUserAgent();
        }

        string GetUserAgent()
        {
            string userAgent = "";

            switch (AgentList.SelectedValue)
            {
                case "Internet Explorer":
                    userAgent = @"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)";
                    break;

                case "Mozilla Firefox":
                    userAgent = @"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3";
                    break;

                case "Google Chrome":
                    userAgent = @"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/6.0";
                    break;

                case "Opera":
                    userAgent = @"Opera/9.64(Windows NT 5.1; U; en) Presto/2.1.1";
                    break;

                case "Googlebot":
                    userAgent = @"Googlebot/2.1 (+http://www.googlebot.com/bot.html)";
                    break;

                case "Custom...":
                    userAgent = AgentBox.Text.Trim();
                    break;
            }

            return userAgent;
        }

        void ShowHeaders(HttpWebRequest request, HttpWebResponse response)
        {
            StringBuilder sbRequest = new StringBuilder();

            sbRequest.Append("<div class='nooverflow'>");
            sbRequest.Append("<h2>Request Headers</h2>");
            AppendTable(sbRequest, request.Headers);
            sbRequest.Append("</div>");

            RequestHeaders.Text = sbRequest.ToString();
            RequestHeaders.Visible = true;

            StringBuilder sbResponse = new StringBuilder();

            sbResponse.Append("<div class='nooverflow'>");
            sbResponse.Append("<h2>Response Headers</h2>");
            sbResponse.AppendFormat("<strong>Status: {0} / {1}</strong><br /><br />", (int)response.StatusCode, response.StatusDescription);
            AppendTable(sbResponse, response.Headers);
            sbResponse.Append("</div>");

            ResponseHeaders.Text = sbResponse.ToString();
            ResponseHeaders.Visible = true;
        }

        void AppendTable(StringBuilder sb, WebHeaderCollection headers)
        {
            sb.Append("<table border='0' cellpadding='0' cellspacing='0' width='580px' class='header_table'>");

            for (int i = 0; i < headers.Count; i++)
            {
                string name = headers.GetKey(i);
                string val = headers.Get(i);

                sb.Append("<tr>");

                bool alt = (i % 2 == 0);

                sb.Append(alt ? "<td class='header_td1'>" : "<td class='header_td2'>");
                sb.Append(name);
                sb.Append("</td>");

                sb.Append(alt ? "<td class='header_td1'>" : "<td class='header_td2'>");
                sb.Append(val);
                sb.Append("</td>");

                sb.Append("</tr>");
            }

            sb.Append("</table>");
            sb.Append("<br />");
        }

        void ProcessResponse(string response)
        {
            response = response.Replace("<", "&lt;");
            //result = result.Replace(">", "&rt;");

            ResultLiteral.Text = "<div class='nooverflow'><h2>Response Content</h2><pre class='brush: html; toolbar: false; wrap-lines: true;'>\r\n" + response + "\r\n</pre></div>";
        }
    }
}
